/************************************************
 * Copyright (c) 2007 ~ 2009, 
 * All rights reserved.
 * Version   : 1.0
 * Author    : lengsh@gmail.com 
 * Date      : 2009.1.2
 ************************************************/

#ifndef  __EVENTS_CONNECTION__H__
#define  __EVENTS_CONNECTION__H__

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <string>
#include <iostream>
#include <glib.h>
#include "define.h"
#include "consDriver.h"
#include "antxdef.h"

using namespace std;

class FGrid{
public:
        string value;   /* mybe nickname, etc.  */
        long lasttime;  /* last update time     */
        char status;    /* if have all friends in frs, is 'y' then yes, else ('n') mean not all  */
        char type;      /* mybe msn or qq       */
        char *owner;    /* current user name    */
        GHashTable *frs;  /* friends name list  */
	FGrid(char *user, long l=0): lasttime(l){
                owner = user; 
                status = 'n';
                type = '\001';
		frs = g_hash_table_new(g_str_hash, g_str_equal);
	}
	virtual ~FGrid(){
		if(frs!=NULL)
			g_hash_table_destroy(frs);
	}
} ;
void g_free_FGrid(void * fg);
class Events
{
	protected:
                string m_scName;
                string m_scLib;
                string m_scConf;
	        int m_iGCSize;
		float m_fGCFactor;
		int m_iKickout;
                int m_ikickout;   // stemp for m_iKickout

                int m_iUpdateMax;
                int m_iReturnType;
                int m_iReturnMaxCounts;
 
		GStaticRWLock  _Lock; /* lock for m_TB  */
		GHashTable *m_TB;    /* user grid  */

//		GHashTable *m_TU;   /*  user who should be update  */
//		GStaticRWLock  _uLock;  /* update user list  */
/***
  void to make deadlock, WE MUST
  first lock _Lock
  then lock _uLock
**/
		ConsumerDriver *m_pCons;
	public:
		int setUpdateMax(int imax){
			int old = m_iUpdateMax;
			if(imax > 0)
				m_iUpdateMax = imax;
			return old; 
		} 
		int setReturnType (int it){ 
			int old = m_iReturnType; 
			if(it >= 0)
				m_iReturnType = it;
			return old; 
		} 
		int setReturnMaxCounts(int imax){ 
			int old = m_iReturnMaxCounts;
			if(imax > 0)
				m_iReturnMaxCounts = imax; 
			return old; 
		} 

		float setFactor(float f){ 
			float ol = m_fGCFactor;
			if(f<1.0 && f>0.0)
				m_fGCFactor = f;
			return ol;
		}
		int setKickout(int k){ 
			int od = m_iKickout;
			if(k > 0)
				m_iKickout = k;
			return od;
		}
		int setGCSize(int g){  
			int od = m_iGCSize;
			if(g> 100)
				m_iGCSize = g;
			return od;
		} 

	public:
		Events(const char *name, const char *lib, const char *conf, int isize, float fFactor, int kickout);
		~Events();
		bool Initialize();
		bool Process_Worklist(long lt);
		bool GC(long lt, int size);
		int Get_Users_Graph(char *user1, char *user2,int limit, int offset, conn *c); 
		int Get_User_Friends(char *user, int limit, int offset, conn *c); 
		int Get_User_Friends(char *user, unsigned type,int limit, int offset, conn *c);
        	int Get_Users_Value(char *user, conn *c);
                int Reload_User(const char *user);
		int Get_Status(string &status);
                bool Clear();
	private:
		int prepare_User_Friends(char *user, long lt);
		bool reload_User_Friends(char *user, FGrid *fs, long lt);
		int get_users_graph(char *user1, char *user2, int limit, int offset, conn *c);
		int get_users_friends(FGrid *fs, unsigned start,unsigned num, conn *c);
		int get_users_friends(FGrid *fs, unsigned type, unsigned start, unsigned num, conn *c);

};

#endif  // __EVENTS_CONNECTION__H__
